home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / fractals / mandelsquare / mandelsquare-1.06.lha / Double.c next >
C/C++ Source or Header  |  1992-12-20  |  12KB  |  495 lines

  1. /*
  2. **    MandelSquare - AmigaDOS 2.0/3.0 Mandelbrot set explorer
  3. **
  4. **    Double.c, Display double-buffering routines
  5. **
  6. **    Copyright © 1991-1992 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10.     /* Double buffering info. */
  11.  
  12. struct DBI
  13. {
  14.     struct Screen        *Screen,        /* Current display. */
  15.                 *NewScreen;        /* Local display. */
  16.     struct Window        *NewWindow;        /* Local window. */
  17.  
  18.     struct ScreenBuffer    *ScreenBuffer[2];    /* v39 double buffering info. */
  19.     struct MsgPort        *ScreenPort;        /* v39 double buffering sync port. */
  20.     struct BitMap        *UncompBitMap;        /* v39 uncompression bitmap */
  21.  
  22.     struct BitMap        *OriginalBitMap;    /* Old display bitmap. */
  23.  
  24.     struct Palette        *OriginalPalette;    /* Original display palette. */
  25.     struct Palette        *BlackPalette;        /* Paint it black. */
  26.  
  27.     struct BitMap        *BitMap[2];        /* v37 double buffering bitmaps. */
  28.  
  29.     struct timerequest    *TimeRequest;        /* Timer io for inter-frame delays. */
  30.     struct MsgPort        *TimePort;
  31. };
  32.  
  33.     /* Are we running under control of Kickstart 3.0 or higher? */
  34.  
  35. extern BYTE        Is39;
  36.  
  37.     /* Safe shared window closing routine. */
  38.  
  39. extern VOID        CloseWindowSafely(struct Window *Window);
  40.  
  41.     /* Bitmap allocation routines. */
  42.  
  43. extern VOID        FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard);
  44. extern struct BitMap *    AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard);
  45.  
  46.     /* Palette management. */
  47.  
  48. extern VOID        FreePalette(struct Palette *Palette);
  49. extern struct Palette *    AllocPalette(LONG NumColours,BYTE TrueColour);
  50. extern struct Palette *    GetPalette(struct Screen *Screen,struct Palette *Palette);
  51. extern VOID        LoadPalette(struct Screen *Screen,struct Palette *Palette,LONG NumColours);
  52. extern LONG        GetPaletteSize(struct Palette *Palette);
  53. extern BYTE        GetPaletteTriplet(struct Palette *Palette,UBYTE *Triplet,LONG Index);
  54. extern BYTE        SetPaletteTriplet(struct Palette *Palette,UBYTE R,UBYTE G,UBYTE B,LONG Index);
  55. extern ULONG        GetPaletteEntry(struct Palette *Palette,LONG Index);
  56. extern BYTE        SetPaletteEntry(struct Palette *Palette,ULONG Entry,LONG Index);
  57.  
  58.     /* Local routines. */
  59.  
  60. VOID            FreeDBI(struct DBI *Info);
  61. struct DBI *        AllocDBI(struct Screen *Screen);
  62. VOID            SwapDBI(struct DBI *Info,BYTE Copy);
  63. struct BitMap *        GetDBI(struct DBI *Info);
  64. VOID            PaletteDBI(struct DBI *Info,struct Palette *Palette);
  65. VOID            StartDBI(struct DBI *Info,ULONG Jiffies);
  66. VOID            WaitDBI(struct DBI *Info);
  67.  
  68.     /* FreeDBI(struct DBI *Info):
  69.      *
  70.      *    Free double-buffering information.
  71.      */
  72.  
  73. VOID
  74. FreeDBI(struct DBI *Info)
  75. {
  76.     WORD i;
  77.  
  78.         /* Release timer io request. */
  79.  
  80.     if(Info -> TimeRequest)
  81.     {
  82.         if(Info -> TimeRequest -> tr_node . io_Device)
  83.             CloseDevice(Info -> TimeRequest);
  84.  
  85.         DeleteIORequest(Info -> TimeRequest);
  86.     }
  87.  
  88.         /* Releae timer io reply port. */
  89.  
  90.     if(Info -> TimePort)
  91.         DeleteMsgPort(Info -> TimePort);
  92.  
  93.         /* Turn the screen black before we change
  94.          * the bitmap.
  95.          */
  96.  
  97.     if(Info -> BlackPalette && !Info -> NewScreen)
  98.     {
  99.         LoadPalette(Info -> Screen,Info -> BlackPalette,0);
  100.  
  101.         FreePalette(Info -> BlackPalette);
  102.     }
  103.  
  104.         /* Reinstall the original viewport bitmap. */
  105.  
  106.     if(Info -> OriginalBitMap)
  107.     {
  108.         Info -> Screen -> ViewPort . RasInfo -> BitMap = Info -> OriginalBitMap;
  109.  
  110.         MakeScreen(Info -> Screen);
  111.  
  112.         RethinkDisplay();
  113.     }
  114.  
  115.         /* Release the display bitmaps. */
  116.  
  117.     for(i = 0 ; i < 2 ; i++)
  118.     {
  119.         if(Info -> BitMap[i])
  120.             FreeCustomBitMap(Info -> BitMap[i],FALSE);
  121.     }
  122.  
  123.         /* Release the uncompression bitmap. */
  124.  
  125.     if(Info -> UncompBitMap)
  126.         FreeCustomBitMap(Info -> UncompBitMap,TRUE);
  127.  
  128.         /* Free the double-buffering information. */
  129.  
  130.     for(i = 0 ; i < 2 ; i++)
  131.     {
  132.         if(Info -> ScreenBuffer[i])
  133.             FreeScreenBuffer(Info -> NewScreen,Info -> ScreenBuffer[i]);
  134.     }
  135.  
  136.         /* Reset the screen palette. */
  137.  
  138.     if(Info -> OriginalPalette && !Info -> NewScreen)
  139.     {
  140.         LoadPalette(Info -> Screen,Info -> OriginalPalette,0);
  141.  
  142.         FreePalette(Info -> OriginalPalette);
  143.     }
  144.  
  145.         /* Release the double buffering sync port. */
  146.  
  147.     if(Info -> ScreenPort)
  148.         DeleteMsgPort(Info -> ScreenPort);
  149.  
  150.         /* Close the window if any. */
  151.  
  152.     if(Info -> NewWindow)
  153.         CloseWindowSafely(Info -> NewWindow);
  154.  
  155.         /* Bring the original screen to the front. */
  156.  
  157.     if(Info -> NewScreen)
  158.     {
  159.         ScreenToFront(Info -> Screen);
  160.  
  161.         CloseScreen(Info -> NewScreen);
  162.     }
  163.  
  164.         /* Free the info buffer. */
  165.  
  166.     FreeVec(Info);
  167. }
  168.  
  169.     /* AllocDBI(struct Screen *Screen):
  170.      *
  171.      *    Allocate double-buffering information handle.
  172.      */
  173.  
  174. struct DBI *
  175. AllocDBI(struct Screen *Screen)
  176. {
  177.     struct DBI *Info;
  178.  
  179.         /* Allocate the buffer. */
  180.  
  181.     if(Info = (struct DBI *)AllocVec(sizeof(struct DBI),MEMF_ANY | MEMF_CLEAR))
  182.     {
  183.         Info -> Screen = Screen;
  184.  
  185.             /* Get the screen palette. */
  186.  
  187.         if(Info -> OriginalPalette = GetPalette(Screen,NULL))
  188.         {
  189.                 /* Allocate blank palette. */
  190.  
  191.             if(Info -> BlackPalette = AllocPalette(GetPaletteSize(Info -> OriginalPalette),FALSE))
  192.             {
  193.                 BYTE Success;
  194.                 WORD i;
  195.  
  196.                     /* Are we running under control of
  197.                      * Kickstart 3.0 or higher?
  198.                      */
  199.  
  200.                 if(Is39)
  201.                 {
  202.                     struct Rectangle    DisplayClip;
  203.                     ULONG            Mode;
  204.  
  205.                         /* Just in case... */
  206.  
  207.                     Success = FALSE;
  208.  
  209.                         /* Obtain the main screen mode ID. */
  210.  
  211.                     Mode = GetVPModeID(&Screen -> ViewPort);
  212.  
  213.                         /* Query the overscan dimensions,
  214.                          * we wish to center the screen
  215.                          * on the display if possible.
  216.                          */
  217.  
  218.                     if(QueryOverscan(Mode,&DisplayClip,OSCAN_VIDEO))
  219.                     {
  220.                         LONG Differ;
  221.  
  222.                             /* Determine intervening space. */
  223.  
  224.                         Differ = ((DisplayClip . MaxX - DisplayClip . MinX + 1) - Screen -> Width) / 2;
  225.  
  226.                             /* Adjust position. */
  227.  
  228.                         DisplayClip . MinX += Differ;
  229.                         DisplayClip . MaxX -= Differ;
  230.  
  231.                             /* Open local screen,
  232.                              * don't mess with the
  233.                              * original screen.
  234.                              */
  235.  
  236.                         if(Info -> NewScreen = OpenScreenTags(NULL,
  237.                             SA_Width,    Screen -> Width,
  238.                             SA_Height,    Screen -> Height,
  239.                             SA_DClip,    &DisplayClip,
  240.                             SA_Left,    DisplayClip . MinX,
  241.                             SA_Depth,    Screen -> RastPort . BitMap -> Depth,
  242.                             SA_DisplayID,    Mode,
  243.                             SA_Font,    Screen -> Font,
  244.                             SA_ShowTitle,    FALSE,
  245.                             SA_Quiet,    TRUE,
  246.                             SA_AutoScroll,    TRUE,
  247.                             SA_Behind,    TRUE,
  248.                         TAG_END))
  249.                         {
  250.                             struct Window *Window = Screen -> FirstWindow;
  251.  
  252.                                 /* The simple way to make sure that
  253.                                  * the screen remains black.
  254.                                  */
  255.  
  256.                             LoadPalette(Info -> NewScreen,Info -> BlackPalette,0);
  257.  
  258.                                 /* Open a window our the local
  259.                                  * screen, just in case the user
  260.                                  * clicks the left mouse button.
  261.                                  */
  262.  
  263.                             if(Info -> NewWindow = OpenWindowTags(NULL,
  264.                                 WA_Width,    Screen -> Width,
  265.                                 WA_Height,    Screen -> Height,
  266.                                 WA_Borderless,    TRUE,
  267.                                 WA_Backdrop,    TRUE,
  268.                                 WA_RMBTrap,    TRUE,
  269.                                 WA_CustomScreen,Info -> NewScreen,
  270.                             TAG_DONE))
  271.                             {
  272.                                     /* Copy the input port. */
  273.  
  274.                                 Info -> NewWindow -> UserPort = Window -> UserPort;
  275.  
  276.                                     /* Install the standard main window IDCMP flags. */
  277.  
  278.                                 ModifyIDCMP(Info -> NewWindow,IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUVERIFY);
  279.  
  280.                                     /* Clear the mouse pointer. */
  281.  
  282.                                 SetPointer(Info -> NewWindow,Window -> Pointer,1,16,0,0);
  283.  
  284.                                     /* Create the sync port. */
  285.  
  286.                                 if(Info -> ScreenPort = CreateMsgPort())
  287.                                 {
  288.                                     Success = TRUE;
  289.  
  290.                                         /* Allocate the double-buffering
  291.                                          * information.
  292.                                          */
  293.  
  294.                                     for(i = 0 ; Success && i < 2 ; i++)
  295.                                     {
  296.                                         if(Info -> ScreenBuffer[i] = AllocScreenBuffer(Info -> NewScreen,NULL,(i ? NULL : SB_SCREEN_BITMAP)))
  297.                                         {
  298.                                             Info -> ScreenBuffer[i] -> sb_DBufInfo -> dbi_DispMessage . mn_ReplyPort = Info -> ScreenPort;
  299.  
  300.                                             BltBitMap(Screen -> RastPort . BitMap,0,0,Info -> ScreenBuffer[i] -> sb_BitMap,0,0,Info -> Screen -> Width,Info -> Screen -> Height,0xC0,0xFF,NULL);
  301.                                         }
  302.                                         else
  303.                                             Success = FALSE;
  304.                                     }
  305.  
  306.                                     if(Success)
  307.                                     {
  308.                                             /* Allocate the temporary bitmap
  309.                                              * data is to be uncompressed in.
  310.                                              */
  311.  
  312.                                         if(Info -> UncompBitMap = AllocCustomBitMap(Screen -> RastPort . BitMap -> Depth,Screen -> Width,Screen -> Height,TRUE))
  313.                                         {
  314.                                                 /* Bring the new screen to the front. */
  315.  
  316.                                             ScreenToFront(Info -> NewScreen);
  317.                                         }